use std::ffi::c_void;
use std::io::{Error,ErrorKind,Result};
#[derive(Debug, Copy,Default)]
pub struct Raw {
    pub h: Option<*const c_void>,
}

impl Clone for Raw {
    fn clone(&self) -> Self {
        Self { h: self.h.clone() }
    }
}

impl Raw {
    pub fn from_offset(&self, off:usize) -> Self {
        match self.h { 
            Some(p) => Self{ h:Some(((p as usize) + off) as *const c_void)},
            None => Self{h:None},
        }
    }
    pub fn to_ptr<T>(&self) -> Result<std::ptr::NonNull<T>> {
        match self.h { 
            Some(p) => match std::ptr::NonNull::<T>::new(p as *mut T) {
                    Some(tp) => Ok(tp),
                    None => Err(Error::new(ErrorKind::Other, "null point")),
                },
            None => Err(Error::new(ErrorKind::Other, "raw is none")),
        }
    }
    pub fn to_offset(&self, other: &Raw) -> Result<usize> {
        if self.h == None || other.h == None {
            Err(Error::new(ErrorKind::Other, "sub with None"))
        } else {
            let s = self.h.unwrap() as *const _ as usize;
            let o = other.h.unwrap() as *const _ as usize;
            if o<s {
                Err(Error::new(ErrorKind::Other, "other not in self"))
            } else {
                Ok(o-s)
            }
        }
    }
}
